package com.javaee.xiangyang.handler;

import com.javaee.xiangyang.entity.enmu.BaseStateEnum;
import com.javaee.xiangyang.entity.enmu.impl.CommentState;
import com.javaee.xiangyang.entity.enmu.impl.OrderState;
import com.javaee.xiangyang.entity.enmu.impl.UserState;
import com.javaee.xiangyang.util.CodeEnumUtil;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@MappedJdbcTypes(JdbcType.TINYINT)
@MappedTypes({
        CommentState.class,
        UserState.class,
        OrderState.class
})
public class CodeEnumTypeHandler<E extends Enum<?> & BaseStateEnum> extends BaseTypeHandler<BaseStateEnum> {

    //获取JAVA类
    private Class<E> type;

    //获取子类实现
    public CodeEnumTypeHandler(Class<E> type) {
        if (type == null) {
            throw new IllegalArgumentException("Type argument cannot be null");
        }
        this.type = type;
    }

    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, BaseStateEnum baseStateEnum, JdbcType jdbcType) throws SQLException {
        preparedStatement.setByte(i, (byte) baseStateEnum.getCode());
    }

    @Override
    public BaseStateEnum getNullableResult(ResultSet resultSet, String s) throws SQLException {
        int aLong = resultSet.getByte(s);
        return resultSet.wasNull() ? null : codeOf(aLong);
    }

    @Override
    public BaseStateEnum getNullableResult(ResultSet resultSet, int i) throws SQLException {
        int aLong = resultSet.getByte(i);
        return resultSet.wasNull() ? null : codeOf(aLong);
    }

    @Override
    public BaseStateEnum getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        int aLong = callableStatement.getByte(i);
        return callableStatement.wasNull() ? null : codeOf(aLong);
    }

    //用从数据库获取到的内容通过此方法进行匹配转换
    private E codeOf(int code) {
        try {
            return CodeEnumUtil.codeOf(type, code);
        } catch (Exception ex) {
            throw new IllegalArgumentException("Cannot convert " + code + " to " + type.getSimpleName() + "by code value.", ex);
        }
    }

}
